// Package db db/executor.go 提供数据库执行操作，如插入和执行SQL语句
package db

import (
	"database/sql"                   // 导入标准数据库接口
	"fmt"                            // 导入格式化包
	log "github.com/sirupsen/logrus" // 导入日志库

	"px-table-checksum-go/models" // 导入项目定义的模型
)

// InsertChecksumResult 向 t_checksum 表插入一条校验结果记录
// 参数:
//   - db: 目标数据库连接池 (*sql.DB)，通常是校验库的连接
//   - result: 要插入的校验结果数据 (使用标准模型 *models.ChecksumResult)
//
// 返回值:
//   - error: 如果插入过程中出错，则返回错误
func InsertChecksumResult(db *sql.DB, result *models.ChecksumResult) error {
	// 检查输入参数是否有效
	if db == nil {
		return fmt.Errorf("数据库连接无效 (nil)")
	}
	if result == nil {
		return fmt.Errorf("要插入的校验结果为 nil")
	}

	// 将标准模型 models.ChecksumResult 转换为数据库交互模型 db.ChecksumResult
	// 这是因为数据库模型可能包含特定的 `db` 标签或与表结构更匹配的类型
	dbResult := ConvertFromModelResult(result)
	if dbResult == nil {
		// 转换失败（理论上不应发生，除非 result 为 nil 已被上面检查处理）
		return fmt.Errorf("将校验结果模型转换为数据库模型失败")
	}

	// 构建 SQL INSERT 语句
	// 使用参数占位符 (?) 防止 SQL 注入
	query := `
        INSERT INTO t_checksum 
        (f_dbid, f_schema_name, f_table_name, f_chunk_no, f_min_key, f_max_key, f_chunk_crc32, f_rows_count) 
        VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    `

	// 执行 SQL INSERT 语句
	// 使用 ExecContext (如果需要上下文) 或 Exec
	_, err := db.Exec(query,
		dbResult.DBID,       // f_dbid
		dbResult.SchemaName, // f_schema_name
		dbResult.TableName,  // f_table_name
		dbResult.ChunkNo,    // f_chunk_no
		dbResult.MinKey,     // f_min_key
		dbResult.MaxKey,     // f_max_key
		dbResult.ChunkCRC32, // f_chunk_crc32 (注意类型匹配，数据库是 BIGINT UNSIGNED)
		dbResult.RowsCount,  // f_rows_count (注意类型匹配，数据库是 INT UNSIGNED)
	)

	// 检查执行结果
	if err != nil {
		// 记录详细的错误信息，包括表名和块编号
		log.Errorf("插入 checksum 结果失败 (%s.%s chunk %d): %v",
			dbResult.SchemaName, dbResult.TableName, dbResult.ChunkNo, err)
		// 返回包装后的错误
		return fmt.Errorf("插入 checksum 结果失败 (%s.%s chunk %d): %w",
			dbResult.SchemaName, dbResult.TableName, dbResult.ChunkNo, err)
	}

	// 记录成功插入的日志（可选，可能日志量过大）
	// log.Debugf("成功插入 checksum 结果: %s.%s chunk %d", dbResult.SchemaName, dbResult.TableName, dbResult.ChunkNo)

	return nil // 表示插入成功
}
